Entrenamiento y evaluación de modelos

Fecha de publicación

14 de octubre de 2024

Objetivo del manual

Paquetes a utilizar en este manual:

Código
# instalar/cargar paquetes

sketchy::load_packages(
  c("ggplot2", 
    "viridis", 
    "nnet",
    "caret",
    "glmnet")
  )
Loading required package: nnet

1 Entrenamiento de modelos de aprendizaje estadístico

La lógica detrás de cualquier método de entrenamiento de modelos estadísticos se centra en ajustar un modelo a un conjunto de datos con el fin de capturar la relación entre las variables predictoras y la variable de respuesta. El objetivo principal es aprender patrones subyacentes en los datos para hacer predicciones precisas o interpretar la relación entre las variables.

1.1 Pasos Fundamentales en el Entrenamiento de Modelos Estadísticos:

flowchart LR
    A(Definir el Modelo) --> B("Especificar la\nFunción de Pérdida")
    B --> C("Optimización\ndel Modelo")
    C --> D("Regularización")
    D --> E("Evaluación\ndel Modelo")
    E --> F("¿Es el rendimiento\nsatisfactorio?")
    F -->|"Sí"| G(Modelo\nFinal)
    F -->|No| H("Realizar Ajustes\ne Iteración")
    H --> A

  • Definir el Modelo: Seleccionar el tipo de modelo estadístico (regresión lineal, regresión logística, árboles de decisión, etc.) que se ajusta a la naturaleza del problema y a la estructura de los datos. El modelo define la forma de la función que relaciona las variables predictoras X con la variable de respuesta Y.

  • Especificar una Función de Pérdida (o Costo): La función de pérdida mide la diferencia entre las predicciones del modelo y los valores reales de la variable de respuesta. En los modelos de regresión, un ejemplo común es el error cuadrático medio (MSE), mientras que en clasificación, la entropía cruzada o el logaritmo de la verosimilitud son más adecuados.

  • Optimización del Modelo: El entrenamiento implica minimizar (o maximizar, dependiendo del enfoque) la función de pérdida ajustando los parámetros del modelo. Por ejemplo, en regresión lineal, se busca encontrar los coeficientes que minimicen la suma de los errores cuadráticos entre las predicciones y los valores observados. Métodos comunes para optimización incluyen el descenso de gradiente, la maximización de la verosimilitud y algoritmos especializados como el algoritmo EM.

  • Regularización (en caso necesario): La regularización añade un término de penalización a la función de pérdida para evitar el sobreajuste. Ayuda a mantener el modelo más simple, controlando la magnitud de los coeficientes o reduciendo el número de variables seleccionadas.

  • Evaluación del Modelo: Una vez entrenado, el modelo se evalúa utilizando datos de prueba o técnicas de validación cruzada para estimar su rendimiento en datos no vistos. Las métricas de evaluación, como la precisión, el error absoluto medio o el índice F1, ayudan a determinar si el modelo generaliza bien.

  • **Ajustes e Iteración: Basado en la evaluación del modelo, puede ser necesario ajustar hiperparámetros, cambiar la arquitectura del modelo o realizar preprocesamiento adicional en los datos. Se itera sobre el proceso hasta que se logre un rendimiento satisfactorio.

1.2 Principios Clave:

Generalización: La capacidad del modelo para realizar predicciones precisas en nuevos datos.
Equilibrio entre sobreajuste y subajuste: El modelo debe ser lo suficientemente complejo para capturar patrones relevantes, pero no tan complejo que capture ruido específico del conjunto de entrenamiento.
Interpretabilidad vs. Complejidad: Modelos más complejos pueden proporcionar mejores predicciones, pero suelen ser más difíciles de interpretar.

En resumen, el entrenamiento de modelos estadísticos consiste en ajustar un modelo para que describa con precisión los datos observados y sea capaz de hacer predicciones precisas en nuevos datos, equilibrando la complejidad del modelo y su capacidad de generalización.

2 Validación Cruzada en Regresión Lineal

La validación cruzada se utiliza para evaluar el rendimiento de un modelo de regresión lineal, ayudando a identificar el nivel de ajuste adecuado y a prevenir el sobreajuste. Las técnicas de validación cruzada más comunes son:

k-Fold Cross-Validation: Se divide el conjunto de datos en k subconjuntos (folds). En cada iteración, se entrena el modelo con k-1 subconjuntos y se prueba en el subconjunto restante. El proceso se repite k veces, promediando el error para obtener una estimación del error de generalización.

Leave-One-Out Cross-Validation (LOOCV): Cada observación se usa como conjunto de prueba, y las restantes n-1 observaciones se utilizan para entrenar el modelo. Es útil en conjuntos de datos pequeños, pero puede ser costoso computacionalmente para grandes volúmenes de datos.

Ejemplo en R:

Código
# Generar datos simulados
set.seed(42)
x <- rnorm(100)
y <- 3 * x + rnorm(100, sd = 0.5)

# Crear un marco de datos
datos <- data.frame(x = x, y = y)

# Configuración de validación cruzada 10-fold
control <- trainControl(method = "cv", number = 10)

# Entrenamiento del modelo con validación cruzada
modelo_cv <- train(y ~ x, data = datos, method = "lm", trControl = control)
print(modelo_cv)
Linear Regression 

100 samples
  1 predictor

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 89, 91, 91, 90, 90, 91, ... 
Resampling results:

  RMSE     Rsquared  MAE    
  0.45531  0.98181   0.36177

Tuning parameter 'intercept' was held constant at a value of TRUE

3 Técnicas de Remuestreo

El remuestreo permite evaluar la variabilidad del modelo al entrenarlo varias veces con diferentes subconjuntos del conjunto de datos original. Estas técnicas son útiles cuando el conjunto de datos es pequeño o cuando se desea evaluar la robustez del modelo.

Bootstrap: Es una técnica de remuestreo con reemplazo. Se crean múltiples subconjuntos de datos a partir del original y se entrena el modelo en cada uno de ellos. Permite estimar la incertidumbre de los coeficientes del modelo.

Ejemplo en R con Bootstrap:

Código
# Configuración para el bootstrap
control_boot <- trainControl(method = "boot", number = 100)

# Entrenamiento del modelo con bootstrap
modelo_boot <- train(y ~ x, data = datos, method = "lm", trControl = control_boot)
print(modelo_boot)
Linear Regression 

100 samples
  1 predictor

No pre-processing
Resampling: Bootstrapped (100 reps) 
Summary of sample sizes: 100, 100, 100, 100, 100, 100, ... 
Resampling results:

  RMSE     Rsquared  MAE    
  0.46044  0.98041   0.36018

Tuning parameter 'intercept' was held constant at a value of TRUE

4 Uso de Validación Cruzada para Evaluar Modelos

En regresión lineal, se utilizan medidas de error como el error cuadrático medio (MSE) o el error absoluto medio (MAE) para evaluar el rendimiento del modelo durante la validación cruzada. La validación cruzada permite identificar si el modelo es demasiado complejo (sobreajuste) o demasiado simple (subajuste). Ejemplo en R calculando el MSE:

Código
# Calcular el MSE en el conjunto de prueba
predicciones <- predict(modelo_cv, datos)
mse <- mean((datos$y - predicciones)^2)
cat("Error cuadrático medio (MSE):", mse, "\n")
Error cuadrático medio (MSE): 0.20214 

5 Validación Cruzada y Técnicas de Remuestreo

Validación cruzada es una técnica que permite evaluar el rendimiento de un modelo al dividir los datos en varios subconjuntos (folds), entrenando el modelo en algunos y evaluándolo en otros:

  • k-Fold Cross-Validation: Los datos se dividen en k subconjuntos, y el modelo se entrena k veces, usando k-1 conjuntos para el entrenamiento y uno para la prueba en cada iteración.
  • Leave-One-Out Cross-Validation (LOOCV): Cada instancia de los datos se usa como conjunto de prueba, mientras que el resto se usa para el entrenamiento.
  • Bootstrap: Involucra el remuestreo de los datos con reemplazo para crear múltiples subconjuntos de entrenamiento.

Ejemplo en R:

Código
# Cargar librería caret para validación cruzada
library(caret)

# Generar datos simulados
set.seed(123)
x <- matrix(rnorm(100 * 20), 100, 20)
y <- factor(sample(c("A", "B"), 100, replace = TRUE))

datos_log <- data.frame(x, y)

# Configuración de validación cruzada 10-fold
control <- trainControl(method = "cv", number = 10)

# Entrenamiento del modelo con validación cruzada
modelo_cv <- train(y ~ ., data = datos_log, method = "glm", family = binomial, trControl = control)
print(modelo_cv)
Generalized Linear Model 

100 samples
 20 predictor
  2 classes: 'A', 'B' 

No pre-processing
Resampling: Cross-Validated (10 fold) 
Summary of sample sizes: 90, 89, 90, 91, 89, 91, ... 
Resampling results:

  Accuracy  Kappa    
  0.49788   -0.023208
Código
summary(modelo_cv)

Call:
NULL

Coefficients:
            Estimate Std. Error z value Pr(>|z|)  
(Intercept)  -0.3659     0.2583   -1.42    0.157  
X1            0.0870     0.2775    0.31    0.754  
X2            0.0593     0.2685    0.22    0.825  
X3            0.4065     0.2678    1.52    0.129  
X4            0.2473     0.2622    0.94    0.346  
X5            0.5893     0.2800    2.10    0.035 *
X6           -0.0255     0.2823   -0.09    0.928  
X7           -0.0750     0.2479   -0.30    0.762  
X8            0.3205     0.2569    1.25    0.212  
X9            0.6021     0.2553    2.36    0.018 *
X10          -0.0139     0.2571   -0.05    0.957  
X11          -0.5509     0.2862   -1.92    0.054 .
X12          -0.2202     0.2696   -0.82    0.414  
X13          -0.1534     0.2836   -0.54    0.589  
X14           0.4374     0.2896    1.51    0.131  
X15           0.5737     0.2736    2.10    0.036 *
X16          -0.5108     0.3243   -1.58    0.115  
X17           0.3061     0.2612    1.17    0.241  
X18          -0.3773     0.2526   -1.49    0.135  
X19          -0.3331     0.2487   -1.34    0.180  
X20           0.1238     0.2383    0.52    0.603  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 137.63  on 99  degrees of freedom
Residual deviance: 111.93  on 79  degrees of freedom
AIC: 153.9

Number of Fisher Scoring iterations: 4

6 Uso de Validación Cruzada para Evaluar Modelos

La validación cruzada es utilizada para obtener una estimación del error del modelo. A través de la técnica de validación cruzada se busca identificar la configuración de hiperparámetros que minimiza el error en el conjunto de prueba. Ejemplo en R:

Código
# Configuración para validación cruzada con ajuste de hiperparámetros
control_tune <- trainControl(method = "repeatedcv", number = 10, repeats = 3)

# Entrenamiento con diferentes hiperparámetros para el modelo de regresión logística
grid <- expand.grid(lambda = seq(0, 1, by = 0.1), alpha = seq(0, 1, by = 0.1))
modelo_tune <- train(y ~ ., data = datos_log, method = "glmnet", trControl = control_tune, tuneGrid = grid)
print(modelo_tune)
glmnet 

100 samples
 20 predictor
  2 classes: 'A', 'B' 

No pre-processing
Resampling: Cross-Validated (10 fold, repeated 3 times) 
Summary of sample sizes: 90, 90, 90, 91, 89, 90, ... 
Resampling results across tuning parameters:

  alpha  lambda  Accuracy  Kappa     
  0.0    0.0     0.52886    0.0343446
  0.0    0.1     0.52620    0.0176571
  0.0    0.2     0.54997    0.0550225
  0.0    0.3     0.53293    0.0159150
  0.0    0.4     0.53620    0.0155997
  0.0    0.5     0.55929    0.0594068
  0.0    0.6     0.56263    0.0624496
  0.0    0.7     0.56232    0.0580332
  0.0    0.8     0.55559    0.0392748
  0.0    0.9     0.55559    0.0362088
  0.0    1.0     0.55862    0.0395610
  0.1    0.0     0.52552    0.0320867
  0.1    0.1     0.54293    0.0467734
  0.1    0.2     0.56899    0.0876765
  0.1    0.3     0.55923    0.0517916
  0.1    0.4     0.57838    0.0769984
  0.1    0.5     0.57468    0.0656129
  0.1    0.6     0.55061    0.0026598
  0.1    0.7     0.55024    0.0000000
  0.1    0.8     0.55024    0.0000000
  0.1    0.9     0.55024    0.0000000
  0.1    1.0     0.55024    0.0000000
  0.2    0.0     0.52552    0.0320867
  0.2    0.1     0.53855    0.0366067
  0.2    0.2     0.57808    0.0901100
  0.2    0.3     0.56801    0.0495956
  0.2    0.4     0.55024    0.0000000
  0.2    0.5     0.55024    0.0000000
  0.2    0.6     0.55024    0.0000000
  0.2    0.7     0.55024    0.0000000
  0.2    0.8     0.55024    0.0000000
  0.2    0.9     0.55024    0.0000000
  0.2    1.0     0.55024    0.0000000
  0.3    0.0     0.52552    0.0320867
  0.3    0.1     0.56172    0.0751321
  0.3    0.2     0.56936    0.0584093
  0.3    0.3     0.55024    0.0000000
  0.3    0.4     0.55024    0.0000000
  0.3    0.5     0.55024    0.0000000
  0.3    0.6     0.55024    0.0000000
  0.3    0.7     0.55024    0.0000000
  0.3    0.8     0.55024    0.0000000
  0.3    0.9     0.55024    0.0000000
  0.3    1.0     0.55024    0.0000000
  0.4    0.0     0.52923    0.0393742
  0.4    0.1     0.55522    0.0571448
  0.4    0.2     0.54758   -0.0032926
  0.4    0.3     0.55024    0.0000000
  0.4    0.4     0.55024    0.0000000
  0.4    0.5     0.55024    0.0000000
  0.4    0.6     0.55024    0.0000000
  0.4    0.7     0.55024    0.0000000
  0.4    0.8     0.55024    0.0000000
  0.4    0.9     0.55024    0.0000000
  0.4    1.0     0.55024    0.0000000
  0.5    0.0     0.52923    0.0393742
  0.5    0.1     0.57209    0.0787931
  0.5    0.2     0.55024    0.0000000
  0.5    0.3     0.55024    0.0000000
  0.5    0.4     0.55024    0.0000000
  0.5    0.5     0.55024    0.0000000
  0.5    0.6     0.55024    0.0000000
  0.5    0.7     0.55024    0.0000000
  0.5    0.8     0.55024    0.0000000
  0.5    0.9     0.55024    0.0000000
  0.5    1.0     0.55024    0.0000000
  0.6    0.0     0.52923    0.0393742
  0.6    0.1     0.56542    0.0563986
  0.6    0.2     0.55024    0.0000000
  0.6    0.3     0.55024    0.0000000
  0.6    0.4     0.55024    0.0000000
  0.6    0.5     0.55024    0.0000000
  0.6    0.6     0.55024    0.0000000
  0.6    0.7     0.55024    0.0000000
  0.6    0.8     0.55024    0.0000000
  0.6    0.9     0.55024    0.0000000
  0.6    1.0     0.55024    0.0000000
  0.7    0.0     0.52923    0.0393742
  0.7    0.1     0.55626    0.0262045
  0.7    0.2     0.55024    0.0000000
  0.7    0.3     0.55024    0.0000000
  0.7    0.4     0.55024    0.0000000
  0.7    0.5     0.55024    0.0000000
  0.7    0.6     0.55024    0.0000000
  0.7    0.7     0.55024    0.0000000
  0.7    0.8     0.55024    0.0000000
  0.7    0.9     0.55024    0.0000000
  0.7    1.0     0.55024    0.0000000
  0.8    0.0     0.52923    0.0393742
  0.8    0.1     0.54158   -0.0127255
  0.8    0.2     0.55024    0.0000000
  0.8    0.3     0.55024    0.0000000
  0.8    0.4     0.55024    0.0000000
  0.8    0.5     0.55024    0.0000000
  0.8    0.6     0.55024    0.0000000
  0.8    0.7     0.55024    0.0000000
  0.8    0.8     0.55024    0.0000000
  0.8    0.9     0.55024    0.0000000
  0.8    1.0     0.55024    0.0000000
  0.9    0.0     0.52923    0.0393742
  0.9    0.1     0.54084   -0.0180451
  0.9    0.2     0.55024    0.0000000
  0.9    0.3     0.55024    0.0000000
  0.9    0.4     0.55024    0.0000000
  0.9    0.5     0.55024    0.0000000
  0.9    0.6     0.55024    0.0000000
  0.9    0.7     0.55024    0.0000000
  0.9    0.8     0.55024    0.0000000
  0.9    0.9     0.55024    0.0000000
  0.9    1.0     0.55024    0.0000000
  1.0    0.0     0.52923    0.0393742
  1.0    0.1     0.54721   -0.0059524
  1.0    0.2     0.55024    0.0000000
  1.0    0.3     0.55024    0.0000000
  1.0    0.4     0.55024    0.0000000
  1.0    0.5     0.55024    0.0000000
  1.0    0.6     0.55024    0.0000000
  1.0    0.7     0.55024    0.0000000
  1.0    0.8     0.55024    0.0000000
  1.0    0.9     0.55024    0.0000000
  1.0    1.0     0.55024    0.0000000

Accuracy was used to select the optimal model using the largest value.
The final values used for the model were alpha = 0.1 and lambda = 0.4.

7 Medidas de Evaluación

Las siguientes son medidas comunes para evaluar el rendimiento de un modelo:

Matriz de Confusión: Resume el rendimiento del modelo en términos de verdaderos positivos, falsos positivos, verdaderos negativos y falsos negativos.

Precisión: Proporción de predicciones correctas sobre el total de predicciones. Precisión=TPTP+FP Precisión=TP+FPTP​

\[ \text{Odds} = \frac{\text{Probabilidad de éxito}}{\text{Probabilidad de fracaso}} = \frac{P(E)}{1 - P(E)} \]

Recall (Sensibilidad): Proporción de verdaderos positivos sobre el total de casos positivos. Recall=TPTP+FN Recall=TP+FNTP​

Índice F1: Es la media armónica de la precisión y el recall. F1=2×Precisioˊn×RecallPrecisioˊn+Recall F1=2×Precisioˊn+RecallPrecisioˊn×Recall​

Ejemplo en R:

Código
# Crear una matriz de confusión
pred <- predict(modelo_cv, datos_log)
confusion <- confusionMatrix(pred, datos_log$y)
print(confusion)
Confusion Matrix and Statistics

          Reference
Prediction  A  B
         A 44 17
         B 11 28
                                        
               Accuracy : 0.72          
                 95% CI : (0.621, 0.805)
    No Information Rate : 0.55          
    P-Value [Acc > NIR] : 0.00036       
                                        
                  Kappa : 0.427         
                                        
 Mcnemar's Test P-Value : 0.34470       
                                        
            Sensitivity : 0.800         
            Specificity : 0.622         
         Pos Pred Value : 0.721         
         Neg Pred Value : 0.718         
             Prevalence : 0.550         
         Detection Rate : 0.440         
   Detection Prevalence : 0.610         
      Balanced Accuracy : 0.711         
                                        
       'Positive' Class : A             
                                        
Código
# Obtener precisión, recall e índice F1
precision <- confusion$byClass["Pos Pred Value"]
recall <- confusion$byClass["Sensitivity"]
f1_score <- 2 * ((precision * recall) / (precision + recall))

cat("Precisión:", precision, "\n")
Precisión: 0.72131 
Código
cat("Recall:", recall, "\n")
Recall: 0.8 
Código
cat("Índice F1:", f1_score, "\n")
Índice F1: 0.75862 
  1. Validación Cruzada y División de Conjuntos de Datos

Para evaluar correctamente un modelo, se suele dividir el conjunto de datos en:

Conjunto de entrenamiento: Usado para entrenar el modelo. Conjunto de validación: Utilizado para la selección de hiperparámetros. Conjunto de prueba: Usado para evaluar el rendimiento final.

Ejemplo en R:

Código
# División de los datos en conjunto de entrenamiento y prueba
set.seed(123)
trainIndex <- createDataPartition(datos_log$y, p = 0.8)[[1]]
x_train <- datos_log[trainIndex, ]
y_train <- datos_log$y[trainIndex]
x_test <- datos_log[-trainIndex, ]
y_test <- datos_log$y[-trainIndex]

# Entrenar un modelo en los datos de entrenamiento
modelo_final <- train(x_train, y_train, method = "glm", family = binomial)

# Evaluar en el conjunto de prueba
pred_test <- predict(modelo_final, x_test)
confusion_test <- confusionMatrix(pred_test, y_test)
print(confusion_test)
Confusion Matrix and Statistics

          Reference
Prediction  A  B
         A 11  0
         B  0  9
                                    
               Accuracy : 1         
                 95% CI : (0.832, 1)
    No Information Rate : 0.55      
    P-Value [Acc > NIR] : 6.42e-06  
                                    
                  Kappa : 1         
                                    
 Mcnemar's Test P-Value : NA        
                                    
            Sensitivity : 1.00      
            Specificity : 1.00      
         Pos Pred Value : 1.00      
         Neg Pred Value : 1.00      
             Prevalence : 0.55      
         Detection Rate : 0.55      
   Detection Prevalence : 0.55      
      Balanced Accuracy : 1.00      
                                    
       'Positive' Class : A         
                                    

Esta clase abarca los conceptos de validación cruzada y técnicas de remuestreo, el uso de la validación cruzada para evaluar modelos, las medidas de evaluación (matriz de confusión, precisión, recall, índice F1) y la división de conjuntos de datos. Los ejemplos en R proporcionan un enfoque práctico para cada concepto, ayudando a comprender la importancia de una evaluación adecuada en el aprendizaje estadístico.

7.1 Ejercicio 1


Información de la sesión

R version 4.4.1 (2024-06-14)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.4 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0 
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=es_CR.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=es_CR.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=es_CR.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C       

time zone: America/Costa_Rica
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] nnet_7.3-19       caret_6.0-94      lattice_0.22-6    glmnet_4.1-8     
[5] Matrix_1.7-0      viridis_0.6.5     viridisLite_0.4.2 ggplot2_3.5.1    
[9] knitr_1.48       

loaded via a namespace (and not attached):
 [1] gtable_0.3.5         shape_1.4.6.1        xfun_0.48           
 [4] remotes_2.5.0        htmlwidgets_1.6.4    recipes_1.0.10      
 [7] vctrs_0.6.5          tools_4.4.1          generics_0.1.3      
[10] stats4_4.4.1         parallel_4.4.1       proxy_0.4-27        
[13] tibble_3.2.1         fansi_1.0.6          ModelMetrics_1.2.2.2
[16] pkgconfig_2.0.3      data.table_1.15.4    lifecycle_1.0.4     
[19] stringr_1.5.1        compiler_4.4.1       munsell_0.5.1       
[22] codetools_0.2-20     sketchy_1.0.3        htmltools_0.5.8.1   
[25] class_7.3-22         yaml_2.3.10          prodlim_2024.06.25  
[28] crayon_1.5.3         pillar_1.9.0         MASS_7.3-61         
[31] gower_1.0.1          iterators_1.0.14     rpart_4.1.23        
[34] foreach_1.5.2        nlme_3.1-165         parallelly_1.38.0   
[37] lava_1.8.0           packrat_0.9.2        tidyselect_1.2.1    
[40] digest_0.6.37        stringi_1.8.4        future_1.34.0       
[43] dplyr_1.1.4          reshape2_1.4.4       purrr_1.0.2         
[46] listenv_0.9.1        splines_4.4.1        fastmap_1.2.0       
[49] grid_4.4.1           colorspace_2.1-1     cli_3.6.3           
[52] magrittr_2.0.3       survival_3.7-0       utf8_1.2.4          
[55] e1071_1.7-16         future.apply_1.11.2  withr_3.0.1         
[58] scales_1.3.0         lubridate_1.9.3      timechange_0.3.0    
[61] rmarkdown_2.28       globals_0.16.3       timeDate_4032.109   
[64] gridExtra_2.3        evaluate_1.0.0       hardhat_1.4.0       
[67] rlang_1.1.4          Rcpp_1.0.13          xaringanExtra_0.8.0 
[70] glue_1.8.0           pROC_1.18.5          ipred_0.9-14        
[73] rstudioapi_0.16.0    jsonlite_1.8.9       R6_2.5.1            
[76] plyr_1.8.9